#include <iostream>
#include <unistd.h>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <ctime>
#define PORT 8081

void Usage(std::string proc) {
    std::cout << "Usage: " << "\n\t" << proc << " local_port" << std::endl;
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        Usage(argv[0]);
        return 1;
    }
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        std::cout << "socket error " << std::endl;
        return 2;
    }
     std::cout << "socket： " <<  sockfd << std::endl;
   struct sockaddr_in local;
   memset(&local, 0, sizeof(local));
   local.sin_family = AF_INET;
   local.sin_port = htons(std::stoi(argv[1]));
   // 云服务器绑定ip的时候，一般不能直接绑定明确的ip；
   // 使用INADDR_ANY来绑定机器上所有的ip
   // ip点分十进制转4字节形式：inet_addr
   local.sin_addr.s_addr = htonl(INADDR_ANY);
   if (bind(sockfd,(struct sockaddr*)&local, sizeof(local)) < 0) {
       std::cerr << "bind error" << std::endl;
       return 3;
   }

   char message[1024];
   //服务器是一个软件、程序、周而复始一直在运行，永不退出
   for ( ; ; ) {
       //收数据
       //处理数据
       //写数据
       memset(message, 0, sizeof(message));
       struct sockaddr_in peer;
       socklen_t len = sizeof(peer);
       ssize_t s = recvfrom(sockfd, message, sizeof(message)-1, 0, (struct sockaddr*)&peer, &len);
       if (s > 0) {  
           FILE *in = popen(message, "r");
           if (in == nullptr) {
               continue;
           }
           std::string echo_string;
           char line[128];
           while (fgets(line, sizeof(line), in)) {
               echo_string += line;
           }
          sendto(sockfd, echo_string.c_str(), echo_string.size(), 0, (struct sockaddr*)&peer, len);
          // message[s] = 0;
          // //command命令行命令, ls -a -l -i
          // char *command[64] = {0};
          // command[0] = strtok(message, " ");
          // int i = 1;
          // while (command[i] = strtok(NULL, " ")) {
          //     i++;
          // }
          // if (fork() == 0) {
          //     // 重定向，将原来写入显示器的内容写入套接字中
          //     //dup2(sockfd, 1);
          //     execvp(command[0], command);
          //     std::cerr << "client message# " << command << std::endl;
          //     exit(4);
          // }
          //std::cout << "client -> server(server): " <<  message << std::endl;
          //std::string echo_message = message;
          //echo_message += "_server_";
          //echo_message += std::to_string((long long)time(nullptr));
          //sendto(sockfd, echo_message.c_str(), echo_message.size(), 0, (struct sockaddr*)&peer, len);
       } else {
           //TODO
       }
   }

   close(sockfd);
    return 0;
}
